
#include "xdns-server-state-impl.h"
#include "xdns-server-state-listener.h"
#include <assert.h>
#include <string.h>

using namespace std;

XdnsServerState::XdnsServerState(unsigned short port,
                                 const struct in_addr* address)
: m_port(port),
  m_address(),
  m_listeners()
{
    assert(address != NULL);
    assert(address->s_addr != INADDR_NONE);

    memcpy(&m_address, address, sizeof(struct in_addr));
}

XdnsServerState::~XdnsServerState()
{
}

XdnsError
XdnsServerState::Init(unsigned short port,
                      const struct in_addr* address,
                      XdnsServerState** serverState)
{
    if ((NULL == address) ||
        (INADDR_NONE == address->s_addr) ||
        (NULL == serverState))
    {
        return XE_Inval;
    }

    XdnsServerStateImpl* serverStateImpl = new (nothrow) XdnsServerStateImpl(port, address);
    if (NULL == serverStateImpl)
    {
        return XE_NoMem;
    }

    *serverState = serverStateImpl;
    return XE_Ok;
}

void
XdnsServerState::Release(XdnsServerState* serverState)
{
    if (serverState != NULL)
    {
        delete serverState;
    }
}

void
XdnsServerState::RegisterListener(XdnsServerStateListener& listener)
{
    m_listeners.insert(&listener);
}

void
XdnsServerState::UnregisterListener(XdnsServerStateListener& listener)
{
    m_listeners.erase(&listener);
}

void
XdnsServerState::NotifyListeners(long queryId,
                                 XdnsError error,
                                 const XdnsData* data,
                                 size_t startOffset,
                                 const XdnsHeaderInfo* header)
{
    set<XdnsServerStateListener*>::iterator iter = m_listeners.begin();
    set<XdnsServerStateListener*>::iterator end = m_listeners.end();
    for (; iter != end; ++iter)
    {
        XdnsServerStateListener* listener = *iter;
        assert(listener != NULL);
        listener->ReplyReceived(queryId, error, data, startOffset, header);
    }
}

